/** Gramar for the language SBPSL.
SBPSL is an acronym for "structured" Balanced Pattern Specification Language.
The language is a reduced First Order Logic and as a part of BPSL meant to specify structural aspects of software design patterns.

A specification file has the form:
------------------------------
\<patternname> :=

\exist
var1, var2 \element \C;
var3, var4 \element \M;
var5, var6 \element \C;
var7, var8 \element \V;
predicate1(var2, var7) ^ predicate2(var5, var3) ^ ... ^ predicateN(varX, varY)
-----------------------------
Constraints:
The predicate section follows the variable declaration section.
There is no necessary order in the domains throughout the variable definition section.
There must be at least one variable of some type defined.
The variables of one type might be defined in several statements.  	
 
*/
grammar BPSL;

options{
	language=Java;
	output=AST;
	ASTLabelType=CommonTree;
}

tokens{
	DISJUNCTION = '^';
	ROOT;
	VARDEF;
	FORMULA;
	CLASSDEF;
	TYPEDVARDEF;
	METHODDEF;
}

@header{
	package patternmining.model.construction.bpsl;
}
@lexer::header{
	package patternmining.model.construction.bpsl;
}


//syntactic specification

//a specification is a formula associated to a pattern name
specification	:	PATTERNNAME ':='! formula;

//a formula is a veriable definition section followed by a formula of disjunct atoms this is a sequence of predicates aplied to variables 
formula		:      '\\exist'! vardef predicateSection 
			;

//the variable section contains an arbitray number of variable declarations, mapping an arbitrary number of identifiers to its type
vardef	:	ID (',' ID )* '\\element' type ';' -> ^(type ID+)
		|	ID (',' ID )* '\\element' type ';' vardef -> ^(type ID+) vardef
		;

// type could be specified as a lexikal rule, specifing one token TYPE . Instead it is seen as a syntactic rule, generating 3 tokens.
// This permits specifyng the type threw the token and include the type information in the AST
type		:	'\\C'
			-> CLASSDEF
		|	'\\V'
			-> TYPEDVARDEF
		|	'\\M'
			-> METHODDEF
		;

predicateSection	:	atom | atom DISJUNCTION! predicateSection
		;
		
atom		:	PREDICATE '(' term ',' term ')'
			-> ^(PREDICATE term term)
		;

// a term is maped directly to a variable identifier. theoraticaly a term could be a constant, 
//but in the context of pattern formalization all predicates apply to pattern components and, consequently, are generalized as variables.		
term		:	ID
		;
		

//lexical specification

//the following lexems map to token PREDICATE 
PREDICATE	:     'Defined-in'
		|	'Reference-to-one'
		|	'Reference-to-many'
		|	'Inheritance'
		|	'Creation'
		|	'Invocation'
		|	'Argument'
		|	'Return-type'
		;

// A lexem for token PATTERNNAME may be any alfa-numeric string preceeded by string '\' except Strings '\exist' and '\element' already defined
PATTERNNAME	: 	'\\'( 'a'..'z' | 'A'..'Z' ) ( 'a'..'z' | 'A'..'Z' | '0'..'9' | '-' |'_' )*
		;

// An ID token may be recogniced for any alfa-numeric string not starting with '\' excepting the PREDICATE lexems, already defined
ID		:	( 'a'..'z'	| 'A'..'Z' ) ( 'a'..'z' | 'A'..'Z' | '0'..'9' | '-' |'_' )*
		;

//whitespace, tabulator and newline are matched to token WS and not feeded to the parser
WS  :  (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;}
    ;
